﻿using Castle.DynamicProxy;
using Framework.Core;
using Framework.Core.Io;
using Framework.Remoting.Conventions;

namespace Framework.Remoting.Client
{
    public class ServiceClientFactory : IServiceClientFactory
    {
        private static readonly ProxyGenerator Generator = new ProxyGenerator();
        private readonly IWcfInterceptorFactory wcfInterceptorFactory;

        public ServiceClientFactory()
            : this(
                new WcfInterceptorFactory(new ChannelPerRequest(new CachedChannelFactoryFactory()),
                    new WcfServiceInfoFactory(new ConfigurationManagerAdapter(), new BindingFactory(),
                        new ProtocolFactory())))
        {
        }

        public ServiceClientFactory(IWcfInterceptorFactory wcfInterceptorFactory)
        {
            this.wcfInterceptorFactory = wcfInterceptorFactory;
        }

        internal static ProxyGenerator ProxyGenerator
        {
            get { return Generator; }
        }


        public T CreateProxy<T>(EnvMode envMode)
            where T : class
        {
            return Generator.CreateInterfaceProxyWithoutTarget<T>(GetInterceptors<T>(envMode));
        }


        protected virtual IInterceptor[] GetInterceptors<T>(EnvMode envMode) where T : class
        {
            return new[] {wcfInterceptorFactory.Create<T>(envMode)};
        }
    }
}